package main

import (
	"autochat-script/script"
	"autochat-script/script/api"
	"autochat-script/script/message"

	"path/filepath"
	"strconv"

	"embed"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/samber/lo"
	"io"
	"io/fs"
	"log"
	"net/http"
	"os"
)

//go:embed templates/** favicon.ico
var embeddedFiles embed.FS

// $env:GOOS = "windows"; $env:GOARCH = "amd64"; go build -o build/app.exe main.go

func init() {
	fmt.Println("init ...")

	gin.SetMode(gin.ReleaseMode)
	gin.DefaultWriter = io.Discard // 禁止 Gin 的日志打印
	gin.DisableConsoleColor()
}

func main() {
	r := gin.Default()

	// 使用标准的LoadHTMLGlob用于开发，生产模式下使用嵌入的模板
	if gin.Mode() == gin.DebugMode {
		r.LoadHTMLGlob("templates/**")
		//r.Static("/static", "./static")
		r.StaticFile("/favicon.ico", "./favicon.ico")
	} else {
		templatesSub, _ := fs.Sub(embeddedFiles, "templates")
		r.LoadHTMLFS(http.FS(templatesSub), "*.tmpl")

		r.StaticFileFS("/favicon.ico", "favicon.ico", http.FS(embeddedFiles))
	}

	//可以传入多个全局中间件
	//r.Use(middleware.SetLoginInfo)

	r.GET("/", func(ctx *gin.Context) {
		userCount := len(script.GetList())
		ctx.HTML(http.StatusOK, "index.tmpl", gin.H{
			"userCount": userCount,
		})
	})

	///api/messages
	r.PUT("/pause/:userId", PauseChat)
	r.PUT("/resume/:userId", ResumeChat)
	r.POST("/stop", Stop)
	r.POST("/start", Start)
	r.GET("/chats", GetChats)
	r.GET("/messages/:userId", GetMessages)

	err := r.Run(":9001")
	if err != nil {
		return
	}

}

func GetChats(ctx *gin.Context) {
	userList := lo.Map(script.GetList(), func(it *script.ChatClient, index int) ChatVO {
		account := api.AccountTable[it.UserId]
		return ChatVO{
			UserId:    account[0],
			Nickname:  account[1],
			AvatarUrl: account[2],
			Status:    it.Status,
			Messages:  it.Messages,
		}
	})

	ctx.JSON(200, gin.H{
		"isOk": true,
		"msg":  "操作成功",
		"list": userList,
	})
}

func GetMessages(ctx *gin.Context) {
	userId := ctx.Param("userId")

	client := script.GetClient(userId)

	ctx.JSON(200, gin.H{
		"isOk": true,
		"msg":  "操作成功",
		"list": client.Messages,
	})
}

func Stop(ctx *gin.Context) {
	for _, client := range script.GetList() {
		script.Pause(client)
	}

	for _, client := range script.GetList() {
		client.Disconnect()
	}

	ctx.JSON(200, gin.H{
		"isOk": true,
		"msg":  "操作成功",
	})
}

func Start(ctx *gin.Context) {
	if len(script.GetList()) != 0 {
		ctx.JSON(200, gin.H{
			"isOk": false,
			"msg":  "无需重复执行启动",
		})
	}

	//默认启动360个
	count := ctx.DefaultQuery("count", "360")
	N, _ := strconv.Atoi(count)
	for i := 1; i <= N; i++ {
		userId := "ch_" + strconv.Itoa(i)
		if api.ExistsByUid(userId) {
			client := &script.ChatClient{
				UserId: userId,
			}
			client.Connect()
		}
	}
	script.RandomChat()

	ctx.JSON(200, gin.H{
		"isOk": true,
		"msg":  "操作成功",
	})
}

func PauseChat(ctx *gin.Context) {
	userId := ctx.Param("userId")

	client := script.GetClient(userId)
	if client == nil {
		ctx.JSON(200, gin.H{
			"isOk": false,
			"msg":  "没有找到client",
		})
	}

	script.Pause(client)
	ctx.JSON(200, gin.H{
		"isOk": true,
		"msg":  "操作成功",
	})
}
func ResumeChat(ctx *gin.Context) {
	userId := ctx.Param("userId")
	client := script.GetClient(userId)
	if client == nil {
		ctx.JSON(200, gin.H{
			"isOk": false,
			"msg":  "没有找到client",
		})
	}
	script.Resume(client)

	ctx.JSON(200, gin.H{
		"isOk": true,
		"msg":  "操作成功",
	})
}

func FileDownload(ctx *gin.Context) {
	filePath := ctx.Query("file")
	log.Println("download file = ", filePath)

	if filePath == "" {
		ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "缺少文件路径参数"})
		return
	}

	fileInfo, err := os.Stat(filePath)
	if os.IsNotExist(err) {
		ctx.AbortWithStatusJSON(http.StatusNotFound, gin.H{"error": "要下载的文件不存在"})
		return
	}
	if fileInfo.IsDir() {
		ctx.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "不支持下载目录"})
		return
	}

	// 设置响应头
	ctx.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filepath.Base(filePath)))
	ctx.Header("Content-Type", "application/octet-stream;charset=utf-8")
	ctx.Header("Content-Length", fmt.Sprintf("%d", fileInfo.Size()))

	// 发送文件内容
	http.ServeFile(ctx.Writer, ctx.Request, filePath)
}

// 客户端对象
type ChatVO struct {
	UserId    string `json:"userId"`
	Nickname  string `json:"nickname"`
	AvatarUrl string `json:"avatarUrl"`
	Status    int    `json:"status"` //0

	Messages []message.Message `json:"messages"`
}
